

// 一个type 过滤的小公式 ，
template <bool cond, typename U>
using resolvedType = typename std::enable_if<cond, U>::type;

struct Counter {
  void increase() {
    // Implements
  }
};
// 这里 = nullptr
// 是表示inc_counter的第二个参数有默认实参指针，在实例化函数的时候可以只填一个参数
//而为什么是指针，是因为指针只需要知道type，不需要实例化，如果改成实例
//那nullptr就该填成某个具体的实例，这对于
//只是想用sfina选择合适的函数而言，实在没有必要用更多的精力考虑这里填什么，再者，具体化会有许多麻烦
template <typename T>
void inc_counter(T& intTypeCounter,
                 std::decay_t<decltype(++intTypeCounter)>* = nullptr) {
  ++intTypeCounter;
}

template <typename T>
void inc_counter(T& counterObj,
                 std::decay_t<decltype(counterObj.increase())>* = nullptr) {
  counterObj.increase();
}

// template <typename T>
// void inc_counter(T& intTypeCounter, std::enable_if<std::is_integral_v<T>,
// void> * = nullptr ) {
//	++intTypeCounter;
// }
//
//
// template <typename T>
// void inc_counter(T& counterObj, std::enable_if<std::is_integral_v<T>, void> *
// = nullptr) { 	counterObj.increase();
// }
//

void doSomething() {
  Counter cntObj;
  uint32_t cntUI32;

  // blah blah blah
  inc_counter(cntObj);
  inc_counter(cntUI32);
}

template <typename T>
class Y {
  template <bool cond, typename U>
  using resolvedType = typename std::enable_if<cond, U>::type;

 public:
  template <typename U = T>
  resolvedType<true, U> foo() {
    return 11;
  }
  template <typename U = T>
  resolvedType<false, U> foo() {
    return 12;
  }
};

template <typename T>
class P {
  template <bool cond, typename U>
  using resolveType = typename std::enable_if<cond, U>::type;

 public:
  template <typename U = T>
  double fun(resolveType<true, U>) {
    return 11;
  }

  template <typename U = T>
  double fun(resolveType<false, U>) {
    return 12;
  }
  double fun(
      typename std::enable_if<is_same<std::decay_t<T>, int>::value>::tpye* =
          nullptr) {}
};

template <bool cond, typename U>
using resolveType = typename std::enable_if<cond, U>::type;

using cast_c = char;

template <typename ArgT>
void check(
    ArgT&&,
    typename std::enable_if<is_same<std::decay_t<ArgT>, int>::value>::type* =
        nullptr) {}
